package com.lboyang.remoting.transport.netty.handler;


import com.lboyang.common.exception.RpcException;
import com.lboyang.common.extension.ExtensionLoader;
import com.lboyang.common.factory.SingletonFactory;
import com.lboyang.provider.service.ServiceProvider;
import com.lboyang.provider.service.zkImpl.ZkServiceProviderImpl;
import com.lboyang.common.dto.NrpcRequest;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Description
 *      RPC 请求的处理器
 * @Date 2021/9/12 0:00
 * @author: A.iguodala
 */
@Slf4j
public class RpcRequestHandler {
    private final ServiceProvider serviceProvider;

    public RpcRequestHandler() {
        serviceProvider = ExtensionLoader.getExtensionLoader(ServiceProvider.class).getExtension("provider");
    }

    /**
     * Processing rpcRequest: call the corresponding method, and then return the method
     */
    public Object handle(NrpcRequest rpcRequest) {
        Object service = serviceProvider.getService(rpcRequest.getRpcServiceName());
        return invokeTargetMethod(rpcRequest, service);
    }

    /**
     * 真正调用目标方法
     * @param rpcRequest
     * @param service
     * @return
     */
    private Object invokeTargetMethod(NrpcRequest rpcRequest, Object service) {
        Object result;
        try {
            Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
            result = method.invoke(service, rpcRequest.getParameters());
            log.info("service:[{}] successful invoke method:[{}]", rpcRequest.getInterfaceName(), rpcRequest.getMethodName());
        } catch (NoSuchMethodException | IllegalArgumentException | InvocationTargetException | IllegalAccessException e) {
            throw new RpcException(e.getMessage(), e);
        }
        return result;
    }
}
